/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

using namespace std;

int tipoRep;
int cantidadDePoblacionesEnGpu;
int cantidadDePoblacionesEnCpu;
int cantidadDeHilosEnLasPoblacionesDeLaGpu;
int cantidadDeHilosEnLasPoblacionesDeLaCpu;
int memoriaCompartidaEnLaGpu;
char* calcularFitnessEnGpu;
char* representacion;
char* operadorCruzamiento;
char* operadorMutacion;
char* metodoDeSeleccion;
char* mecanismosDeReemplazo;
char* metodoInicializacion;
int tamanioPoblacion;
char* criterioDeParada;
char* funcionFitness;
int cantidadGenesPorIndividuo;


int parsearCruzamiento(char* palabra){
  int cruzamiento = -1;
cout << "tipoRep" << tipoRep;
  switch (tipoRep) {
	case 0: {//representacion binaria
		if(strcmp(palabra,"1punto")==0) cruzamiento = 0;
  		else if(strcmp(palabra,"2puntos")==0) cruzamiento = 1;
  		else if(strcmp(palabra,"uniforme")==0) cruzamiento = 2;
		else cruzamiento = -3;
	}
	break;
	case 1: {//representacion entera
		if(strcmp(palabra,"1punto")==0) cruzamiento = 0;
  		else if(strcmp(palabra,"2puntos")==0) cruzamiento = 1;
  		else if(strcmp(palabra,"uniforme")==0) cruzamiento = 2;
	}
	break;
	case 2: {//representacion permutacion
		if(strcmp(palabra,"pmx")==0) cruzamiento = 0;
  		else if(strcmp(palabra,"ox")==0) cruzamiento = 1;
  		else if(strcmp(palabra,"cx")==0) cruzamiento = 2;
		else if(strcmp(palabra,"er")==0) cruzamiento = 3;
	}
	break;
	case 3: {//representacion real
		if (strcmp(palabra,"aritmetico")==0) cruzamiento = 0;
		else if(strcmp(palabra,"aritmeticoIndividual")==0) cruzamiento = 1;
  		else if(strcmp(palabra,"aritmeticoSimple")==0) cruzamiento = 2;
  		else if(strcmp(palabra,"aritmeticoCompleto")==0) cruzamiento = 3;
	}
	break;
	default:
	break;

  }
  return cruzamiento;
}

int parsearMutacion(char* palabra){
  int mutacion = -1;
  switch (tipoRep) {
	case 0: {//representacion binaria
		if(strcmp(palabra,"inversion")==0) mutacion = 0;
	}
	break;
	case 1: {//representacion entera
		if(strcmp(palabra,"reajusteAleatorio")==0) mutacion = 0;
  		else if(strcmp(palabra,"porDeslizamiento")==0) mutacion = 1;
	}
	break;
	case 2: {//representacion permutacion
		if(strcmp(palabra,"intercambio")==0) mutacion = 0;
  		else if(strcmp(palabra,"insercionSimple")==0) mutacion = 1;
  		else if(strcmp(palabra,"inversion")==0) mutacion = 2;
		else if(strcmp(palabra,"mezcla")==0) mutacion = 3;
	}
	break;
	case 3: {//representacion real
		if (strcmp(palabra,"uniforme")==0) mutacion = 0;
		else if(strcmp(palabra,"noUniforme")==0) mutacion = 1;
	}
	break;
	default:
	break;

  }
  return mutacion;
}

int parsearSeleccion(char* palabra){
  if(strcmp(palabra,"elitista")==0) return 0;
  else if(strcmp(palabra,"porTorneo")==0) return 1;
  else if(strcmp(palabra,"ruedaDeRuleta")==0) return 2;
  else if(strcmp(palabra,"muestreoEstocasticoUniversal")==0) return 3;
  else if(strcmp(palabra,"porRango")==0) return 4;
  else if(strcmp(palabra,"porTruncamiento")==0) return 5;
  else if(strcmp(palabra,"torneoEstocastico")==0) return 6;
  else return -1;
}

int parsearReemplazo(char* palabra){
  if(strcmp(palabra,"reemplazoGeneracional")==0) return 0;
  else if(strcmp(palabra,"estadoEstacionario")==0) return 1;
  else if(strcmp(palabra,"saltoGeneracional")==0) return 2;
  else if(strcmp(palabra,"elitismo")==0) return 3;
  else return -1;
}

int parsearRepresentacion(char* palabra){
  //0 binaria
  //1 entera
  //2 permutacion
  //3 real
  if(strcmp(palabra,"binaria")==0) {tipoRep = 0;return 0;}
  else if(strcmp(palabra,"entera")==0) {tipoRep = 1;return 1;}
  else if(strcmp(palabra,"permutacion")==0) {tipoRep = 2;return 2;}
  else if(strcmp(palabra,"real")==0) {tipoRep = 3;return 3;}
  else {tipoRep = -1;return -1;}
}

int tipoRepresentacionVariable(char* variable, char* valor){

  if(strcmp(variable,"cantidadDePoblacionesEnGpu")==0) return atoi(valor);
  else if(strcmp(variable,"cantidadDePoblacionesEnCpu")==0) return atoi(valor);
  else if(strcmp(variable,"cantidadDeHilosEnLasPoblacionesDeLaGpu")==0) return atoi(valor);
  else if(strcmp(variable,"cantidadDeHilosEnLasPoblacionesDeLaCpu")==0) return atoi(valor);
  else if(strcmp(variable,"memoriaCompartidaEnLaGpu")==0) return atoi(valor);
  else if(strcmp(variable,"calcularFitnessEnGpu")==0) return atoi(valor);
  else if(strcmp(variable,"representacion")==0) return parsearRepresentacion(valor);
  else if(strcmp(variable,"operadorCruzamiento")==0) return parsearCruzamiento(valor);
  else if(strcmp(variable,"operadorMutacion")==0) return parsearMutacion(valor);
  else if(strcmp(variable,"metodoDeSeleccion")==0) return parsearSeleccion(valor);
  else if(strcmp(variable,"mecanismosDeReemplazo")==0) return parsearReemplazo(valor);
  else if(strcmp(variable,"probabilidadCruzamiento")==0) return atoi(valor);
  else if(strcmp(variable,"probabilidadMutacion")==0) return atoi(valor);
  else if(strcmp(variable,"metodoInicializacion")==0) return 0;
  else if(strcmp(variable,"tamanioPoblacion")==0) return atoi(valor);
  else if(strcmp(variable,"numeroGeneraciones")==0) return atoi(valor);
  else if(strcmp(variable,"criterioDeParada")==0) return 0;
  else if(strcmp(variable,"funcionFitness")==0) return 0;
  else if(strcmp(variable,"cantidadGenesPorIndividuo")==0) return atoi(valor);
  else if(strcmp(variable,"gradoNoUniformidad")==0) return atoi(valor);
  else return -2;

}

int parsearVariables(char * linea){
  int contador = 0, i=0;
  char* palabra = (char*) malloc (sizeof(char)*40);
  char* valor = (char*) malloc (sizeof(char)*40);
    i = 0;
    while(linea[contador] != '\0' && linea[contador] != ':'){
      palabra[i] = linea[contador];
      i++;
      contador++;
    }
    if(linea[contador] == ':')
      contador++;
    palabra[i] = '\0';
    i = 0;
    while(linea[contador] != '\0' && linea[contador] != ':'){
      valor[i] = linea[contador];
      i++;
      contador++;
    }
    valor[i] = '\0';
    int a = tipoRepresentacionVariable(palabra,valor);
    //cout << palabra << ":" << a;
    //cout << " " << valor << "\n";
    return a;
}


int *obtenerParametros () {
  FILE * pFile;
  long lSize;
  char * buffer;
  size_t result;
  pFile = fopen ("archivoConfiguracion", "rb");
  if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);
  // allocate memory to contain the whole file:
  buffer = (char*) malloc (sizeof(char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);
  if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

  // the whole file is now loaded in the memory buffer.

  // terminate
  fclose (pFile);

  char * linea;
  linea = (char*) malloc (sizeof(char)*lSize);
  int contador = 0;
  int  i;
  int tamResultado = sizeof(int)*19;
  int *resultado = (int *) malloc(tamResultado);

  int j = 0;
  while(contador<lSize){
    i = 0;
    while(buffer[contador] != '\n' && contador<lSize){
	//cout << "chau";
      linea[i] = buffer[contador];
      i++;
      contador++;
    }
    linea[i] = '\0';
    contador ++;
    resultado[j] = parsearVariables(linea);
    if (resultado[j] < 0) {fputs ("Error de configuracion",stderr); exit (3);}
    j++;
  }

//  cout <<"\n ** resultado **\n";
//  for (int i = 0; i<18; i++){
//	  cout <<resultado[i]<<" ";
//  }
//  cout <<"\n";
  free (buffer);
  return resultado;
}

